home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / portfoli / bootst11.lzh / PF BOOTSTRAP VATIPX PSLIPC < prev    next >
Text File  |  1991-05-02  |  5KB  |  234 lines

  1. #ifndef lint
  2. static char *sccsid = "%W%    MS/ACF    %E%";
  3. #endif
  4. /*
  5.  *  tip/slip.c
  6.  *
  7.  *  This file contains the SLIP specific startup code.  It is designed
  8.  *  with both BSD sockets and Sun Streams in mind, though the socket
  9.  *  version has not been tested lately (but it SHOULD work).  The Streams
  10.  *  code is for SunOS 4.0[.1].
  11.  *
  12.  *  The code to set the route (basically an internal shell script) may
  13.  *  need tweeking on other systems, though it works on any of the
  14.  *  systems I have run into.
  15.  *
  16.  *  The alarm/DCD code is a HACK to detect loss of the line in the
  17.  *  absense of proper modems status signaling (broken in SunOS when
  18.  *  using the dialout device, serial line minor devices 128-255).
  19.  *  This has been reported, but I suspect that a fix will have to
  20.  *  wait for SunOS 4.2 or maybe 4.1.?.
  21.  *
  22.  *  Doug Kingston <dpk@morgan.com>
  23.  *  880219
  24.  */
  25.  
  26. #include "tip.h"
  27.  
  28. #include <sys/socket.h>
  29. #ifdef STREAMS
  30. #include <sys/stropts.h>
  31. #include <sys/sockio.h>
  32. #include <sys/termios.h>    /* has defines that clash with ioctl.h */
  33. /* #include <sys/slip.h>  */
  34. #include "slip.h"
  35. #endif STREAMS
  36. #include <netinet/in.h>
  37. #include <net/if.h>
  38.  
  39. #include <arpa/inet.h>
  40.  
  41. #define    DCD_SETTLING_TIME 1    /* time between DCD change and status check */
  42. #define    DCD_CHECK_INTERVAL 15    /* if > 0, time between automatic DCD checks */
  43.  
  44. int gotsig = 0;
  45. sigfunc_t dcd_handler();
  46.  
  47. runslip()
  48. {
  49.     int unit, s;
  50.     struct ifreq ifr;
  51. #ifdef I_POP /* Using streams */
  52.     struct termios tios;
  53.  
  54.     /* pop all streams modules */
  55.     while (ioctl(FD, I_POP, 0) == 0)
  56.         continue;
  57.  
  58.     /* set up the line parameters */
  59.     if (ioctl(FD, TCGETS, (caddr_t)&tios) < 0) {
  60.         perror("ioctl (TCGETS)");
  61.         return(1);
  62.     }
  63.     tios.c_cflag = (tios.c_cflag&(CBAUD|CIBAUD))|CS8|CREAD|HUPCL;
  64.     tios.c_iflag = IGNBRK;
  65.     if (ioctl(FD, TCSETS, (caddr_t)&tios) < 0) {
  66.         perror("ioctl (TCSETS)");
  67.         return(1);
  68.     }
  69.  
  70.     /* push the SLIP module */
  71.     if (ioctl(FD, I_PUSH, "slip") < 0) {
  72.         perror("ioctl (I_PUSH)");
  73.         return(1);
  74.     }
  75.  
  76.     /* find out what unit number we were assigned */
  77.     if (ioctl(FD, SLIOGUNIT, (caddr_t)&unit) < 0) {
  78.         perror("ioctl (SLIOGUNIT)");
  79.         return(1);
  80.     }
  81. #else /* not streams */
  82.     int ldisc = SLIPDISC;
  83.     if (ioctl(FD, TIOCSETD, &ldisc) < 0) {
  84.         perror("slipd: TIOCSETD");
  85.         return(1);
  86.     }
  87.     if (ioctl(FD, TIOCGETD, &unit) < 0) {    /* Hack to get slip number */
  88.         perror("slipd: TIOCGETD");
  89.         return(1);
  90.     }
  91. #endif I_POP
  92.  
  93.     /* set the local and remote interface addresses */
  94.     s = socket(AF_INET, SOCK_DGRAM, 0);
  95.  
  96.     (void) sprintf(ifr.ifr_name, "slip%d", unit);
  97.     if (in_getaddr(DA, &ifr.ifr_addr) != 0 ||
  98.         ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
  99.         perror("ioctl (SIOCSIFDSTADDR)");
  100.         return(1);
  101.     }
  102.  
  103.     /* this has the side-effect of marking the interface up */
  104.     if (in_getaddr(SA, &ifr.ifr_addr) != 0 ||
  105.         ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
  106.         perror("ioctl (SIOCSIFADDR)");
  107.         return(1);
  108.     }
  109.  
  110.     if (in_getaddr(SM, &ifr.ifr_addr) != 0) {
  111.         if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
  112.             perror("ioctl (SIOCSIFADDR)");
  113.             return(1);
  114.         }
  115.     }
  116.  
  117.     /* Set up default route if desired and not already present */
  118.     if (boolean(value(SETROUTE))) {
  119.         char buf[256];
  120.         char *argv[4];
  121.         char *envp[2];
  122.         int status;
  123.  
  124.         sprintf(buf, "if eval 'netstat -r|grep -s \"^default\"';\
  125.                   then echo default route already installed;\
  126.                   else route add 0 %s 3; fi", SA);
  127.         argv[0] = "/bin/sh";
  128.         argv[1] = "-c";
  129.         argv[2] = buf;
  130.         argv[3] = (char *)0;
  131.  
  132.         envp[0] = "PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/etc";
  133.         envp[1] = (char *)0;
  134.  
  135.         switch (fork()) {
  136.         case 0:        /* Child */
  137.             execve(argv[0], argv, envp);
  138.             exit(1);
  139.         case -1:
  140.             perror("tip: route add: fork");
  141.             break;
  142.         default:    /* Parent */
  143.             wait(&status);
  144.         }
  145.     }
  146.  
  147.     fprintf(stderr, "\07[SLIP running]\r\n");
  148.  
  149.     /* set up signal handlers */
  150.     (void) sigblock(sigmask(SIGALRM));
  151.     (void) signal(SIGALRM, dcd_handler);
  152. #if defined(SIGDCD) && SIGDCD > 0
  153.     (void) signal(SIGDCD, dcd_handler);
  154. #endif
  155.  
  156.     /* twiddle thumbs until we get a signal */
  157.     while (1) {
  158.         alarm(DCD_CHECK_INTERVAL);
  159.         sigpause(0);
  160. #if defined(SIGDCD) && SIGDCD > 0
  161.         (void) sigblock(sigmask(SIGALRM)|sigmask(SIGDCD));
  162. #else
  163.         (void) sigblock(sigmask(SIGALRM));
  164. #endif SIGDCD
  165.         if (gotsig && lowdcd(FD)) {
  166.             sleep(DCD_SETTLING_TIME);
  167.             if (lowdcd(FD))
  168.                 break;
  169.         }
  170.         gotsig = 0;
  171.     }
  172.     return(0);
  173. }
  174.  
  175. abort_slip()
  176. {
  177. #ifdef STREAMS
  178.     /* pop the SLIP stream module */
  179.     while(ioctl(FD, I_POP, 0) == 0);
  180. #else
  181.     int ldisc = 0;
  182.     (void)ioctl(FD, TIOCSETD, &ldisc);
  183. #endif
  184. }
  185.  
  186. sigfunc_t
  187. dcd_handler()
  188. {
  189.     gotsig = 1;
  190. }
  191.  
  192. /* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
  193. int
  194. lowdcd(fd)
  195.     int fd;
  196. {
  197.     int mbits;
  198.  
  199.     if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
  200.         return 1;    /* port is dead, we die */
  201.     return !(mbits & TIOCM_CAR);
  202. }
  203.  
  204. in_getaddr(s, saddr)
  205.     char *s;
  206.     struct sockaddr *saddr;
  207. {
  208.     register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
  209.     struct hostent *hp;
  210.     struct netent *np;
  211.     int val;
  212.  
  213.     sin->sin_family = AF_INET;
  214.     val = inet_addr(s);
  215.     if (val != -1) {
  216.         sin->sin_addr.s_addr = val;
  217.         return(0);
  218.     }
  219.     hp = gethostbyname(s);
  220.     if (hp) {
  221.         sin->sin_family = hp->h_addrtype;
  222.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  223.         return(0);
  224.     }
  225.     np = getnetbyname(s);
  226.     if (np) {
  227.         sin->sin_family = np->n_addrtype;
  228.         sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
  229.         return(0);
  230.     }
  231.     fprintf(stderr, "tip: in_getaddr: can't parse/lookup '%s'\n", s);
  232.     return(1);
  233. }
  234.